<template>
  <div class="text-sm">
    <div class="flex items-center justify-between mb-2">
      <div class="font-semibold text-gray-700">复盘目录</div>
      <div class="flex items-center gap-2">
        <button class="p-1 rounded hover:bg-gray-100" @click="setAll(true)" title="展开全部">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-4 h-4 text-gray-700"><path d="M18 15l-6-6-6 6"/></svg>
        </button>
        <button class="p-1 rounded hover:bg-gray-100" @click="setAll(false)" title="折叠全部">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="w-4 h-4 text-gray-700"><path d="M6 9l6 6 6-6"/></svg>
        </button>
        <button class="text-blue-600" @click="createRoot">新建</button>
      </div>
    </div>
    <ul :key="treeKey">
      <TreeNode v-for="n in nodes" :key="n.id" :node="n" :default-expanded="allExpanded" @select="onSelect" @create="create" @rename="rename" @remove="remove" @drop="onDrop" />
    </ul>
  </div>
</template>
<script setup>
import { computed, ref, defineComponent, h, watch } from 'vue'
import { useReviewFolderStore } from '../stores/reviewFolders'

const emit = defineEmits(['select','drop'])
const store = useReviewFolderStore()
const nodes = computed(() => store.tree)
const allExpanded = ref(true)
const treeKey = ref(0)
const setAll = (v) => { allExpanded.value = v; treeKey.value++ }

const onSelect = (id) => emit('select', id)
const onDrop = (payload) => emit('drop', payload)

const createRoot = async () => { const name = prompt('目录名称'); if (name) await store.create(name, null) }
const create = async (parentId) => { const name = prompt('子目录名称'); if (name) await store.create(name, parentId) }
const rename = async (id, currentName, parentId) => { const name = prompt('重命名为：', currentName); if (name && name !== currentName) await store.rename(id, name, parentId) }
const remove = async (id) => { if (confirm('确认删除该目录及其包含的引用？')) await store.remove(id) }

const TreeNode = defineComponent({
  name: 'TreeNode',
  props: { node: { type: Object, required: true }, defaultExpanded: { type: Boolean, default: true } },
  emits: ['select','create','rename','remove','drop'],
  setup(props, { emit }) {
    const expanded = ref(props.defaultExpanded)
    watch(() => props.defaultExpanded, (v) => { expanded.value = v })
    const toggle = () => { expanded.value = !expanded.value }
    const onSelectLocal = () => emit('select', props.node.id)
    const onCreateLocal = () => emit('create', props.node.id)
    const onRenameLocal = () => emit('rename', props.node.id, props.node.name, props.node.parent_id)
    const onRemoveLocal = () => emit('remove', props.node.id)
    const findNode = (id, nodes) => {
      for (const n of nodes) {
        if (n.id === id) return n
        const hit = findNode(id, n.children || [])
        if (hit) return hit
      }
      return null
    }
    const isDescendant = (targetId, possibleAncestorId) => {
      const ancestor = findNode(possibleAncestorId, store.tree)
      if (!ancestor) return false
      const dfs = (n) => {
        if (!n || !n.children) return false
        for (const c of n.children) {
          if (c.id === targetId) return true
          if (dfs(c)) return true
        }
        return false
      }
      return dfs(ancestor)
    }
    const onDropLocal = async (e) => {
      try {
        const rid = Number(e.dataTransfer.getData('text/review-id'))
        if (rid) emit('drop', { folderId: props.node.id, reviewId: rid })
        const draggedFolderId = Number(e.dataTransfer.getData('text/review-folder-id'))
        if (draggedFolderId && draggedFolderId !== props.node.id) {
          if (isDescendant(props.node.id, draggedFolderId)) return
          await store.move(draggedFolderId, props.node.id)
        }
      } catch {}
    }
    const onDragStartLocal = (e) => { try { e.dataTransfer.setData('text/review-folder-id', String(props.node.id)) } catch {} }
    const overBefore = ref(false)
    const onDropBefore = async (e) => {
      e.preventDefault()
      try {
        const draggedFolderId = Number(e.dataTransfer.getData('text/review-folder-id'))
        if (!draggedFolderId || draggedFolderId === props.node.id) return
        await store.reorder(draggedFolderId, { parent_id: props.node.parent_id ?? null, before_id: props.node.id })
      } catch {}
      finally { overBefore.value = false }
    }
    const overAfter = ref(false)
    const onDropAfter = async (e) => {
      e.preventDefault()
      try {
        const draggedFolderId = Number(e.dataTransfer.getData('text/review-folder-id'))
        if (!draggedFolderId || draggedFolderId === props.node.id) return
        await store.reorder(draggedFolderId, { parent_id: props.node.parent_id ?? null, after_id: props.node.id })
      } catch {}
      finally { overAfter.value = false }
    }
    const showMenu = ref(false)
    const toggleMenu = () => { showMenu.value = !showMenu.value }
    const closeMenu = () => { showMenu.value = false }
    const onCreateLocalMenu = () => { closeMenu(); onCreateLocal() }
    const onRenameLocalMenu = () => { closeMenu(); onRenameLocal() }
    const onRemoveLocalMenu = () => { closeMenu(); onRemoveLocal() }
    return () => h('li', { class: 'mb-1 relative' }, [
      h('div', { class: `drop-zone mx-6 my-0 rounded ${overBefore.value ? 'dragover' : ''}`,
        onDragover: (e) => e.preventDefault(),
        onDragenter: () => { overBefore.value = true },
        onDragleave: () => { overBefore.value = false },
        onDrop: onDropBefore }),
      h('div', { class: 'flex items-center justify-between pr-2', draggable: true, onDragstart: onDragStartLocal, onDragover: (e) => e.preventDefault(), onDrop: onDropLocal }, [
        h('div', { class: 'flex items-center gap-1 min-w-0' }, [
          h('button', { class: 'w-5 h-5 flex items-center justify-center text-gray-600', onClick: toggle, title: expanded.value ? '折叠' : '展开' },
            h('svg', { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', 'stroke-width': '2', 'stroke-linecap': 'round', 'stroke-linejoin': 'round', class: 'w-4 h-4' }, [
              h('path', { d: expanded.value ? 'M6 9l6 6 6-6' : 'M9 18l6-6-6-6' })
            ])
          ),
          h('button', { class: 'text-left hover:underline truncate max-w-[180px]', title: props.node.name, onClick: onSelectLocal }, `${props.node.name}${typeof props.node.count==='number' ? ` (${props.node.count})` : ''}`)
        ]),
        h('div', { class: 'relative shrink-0' }, [
          h('button', { class: 'p-1 rounded hover:bg-gray-100', onClick: toggleMenu, title: '更多' },
            h('svg', { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 20 20', fill: 'currentColor', class: 'w-4 h-4 text-gray-600' }, [
              h('path', { d: 'M6 10a2 2 0 11-4 0 2 2 0 014 0zm6 0a2 2 0 11-4 0 2 2 0 014 0zm6 0a2 2 0 11-4 0 2 2 0 014 0z' })
            ])
          ),
          showMenu.value && h('div', { class: 'absolute right-0 mt-1 bg-white border rounded shadow text-sm z-10 min-w-[160px] whitespace-nowrap', onMouseleave: closeMenu }, [
            h('button', { class: 'block w-full text-left px-3 py-2 hover:bg-gray-100', onClick: onCreateLocalMenu }, '新建'),
            h('button', { class: 'block w-full text-left px-3 py-2 hover:bg-gray-100', onClick: onRenameLocalMenu }, '重命名'),
            h('button', { class: 'block w-full text-left px-3 py-2 text-red-600 hover:bg-red-50', onClick: onRemoveLocalMenu }, '删除'),
          ])
        ])
      ]),
      h('div', { class: `drop-zone mx-6 my-0 rounded ${overAfter.value ? 'dragover' : ''}`,
        onDragover: (e) => e.preventDefault(),
        onDragenter: () => { overAfter.value = true },
        onDragleave: () => { overAfter.value = false },
        onDrop: onDropAfter }),
      expanded.value && h('ul', { class: 'pl-6' },
        (props.node.children || []).map(c =>
          h(TreeNode, {
            key: c.id,
            node: c,
            onSelect: (id) => emit('select', id),
            onCreate: (pid) => emit('create', pid),
            onRename: (...args) => emit('rename', ...args),
            onRemove: (id) => emit('remove', id),
            onDrop: (payload) => emit('drop', payload)
          })
        )
      )
    ])
  }
})
</script>
<style>
@import "https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css";
.drop-zone { background: transparent; transition: background-color 0.15s ease; }
.drop-zone.dragover { background: var(--drop-zone-bg); }
</style>
